import json

from django.http import Http404
from django.http import HttpResponse
from django.http import JsonResponse
from django.shortcuts import render
from django.views import View
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView

from booktest.models import BookInfo

# Create your views here.
from booktest.serializers import BookInfoSerializer

# 1、自定义Restful API接口，提供以下五个接口：
# 1）获取所有的图书的信息； GET /books/
# 2）新增一本图书的信息； POST /books/
# 3）获取指定的图书的信息（根据ID）；  GET /books/ID/
# 4）修改指定的图书的信息（根据ID）；   PUT books/ID/
# 5）删除指定的图书的信息（根据ID）。   DELETE /books/ID


# =====================自定义GenericAPIView=======================
class MyGenericAPIView(APIView):
    # 指定当前视图所使用的查询集
    queryset = None
    # 指定当前视图所使用的序列化器类
    serializer_class = None
    # 指定从查询集获取对象时，‘查询字段’的名
    lookup_field = 'pk'
    # 指定查询集获取对象时，从url地址中提取的参数的名称
    lookup_url_kwarg = 'pk'
    def get_serializer_class(self):
        # 指定当前视图所使用的序列化器类是谁
        return self.serializer_class
    def get_serializer(self,*args,**kwargs):
        """创建一个视图所使用序列化器类的对象"""
        # 获取当前视图所使用的序列化器类
        serializer_cls = self.get_serializer_class()
        # 创建一个序列化器类对象
        return serializer_cls(*args,**kwargs)
    def get_queryset(self):
        # 指定当前视图所使用的查询集
        return self.queryset.all()

    def get_object(self):
        """从视图所使用的查询集中获取指定的对象，默认根据pk进行查询"""
        # 获取当前视图所使用的查询集
        query_set = self.get_queryset()

        filters = {
            self.lookup_field:self.kwargs[self.lookup_url_kwarg]
        }
        try:
            obj = query_set.get(**filters)
        except BookInfo.DoesNotExist:
            return Http404
        return obj


# /books/
class BookListView(MyGenericAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer
    def get(self,request):
        """
        1）获取所有的图书的信息； GET /books/
        :param request:
        :return:
        """
        # 1.查询全部的图书信息
        books = self.get_queryset()

        # 2.将对象取出并返回所有图书的json数据，其实就是字典形式，状态码200
        serializer = self.get_serializer(books,many=True)
        # 4.返回数据，其实返回的可以是列表，但是需要将safe参数定义成false
        return Response(serializer.data)

    def post(self,request):
        """
        2）新增一本图书的信息； POST /books/
        需要接收前端的两个参数：btitle / bpub_date
        :param request:
        :return:
        """
        # 反序列化数据-校验
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        # 反序列化数据的保存
        serializer.save()

        # 7.自定义状态码为201
        return Response(serializer.data,status=status.HTTP_201_CREATED)

# /books/id/
class BookDetailView(MyGenericAPIView):
    serializer_class = BookInfoSerializer
    #指定当前视图所使用的查询集
    queryset = BookInfo.objects.all()
    def get(self,request,pk):
        """
        3）获取指定的图书的信息（根据ID）；  GET /books/ID/
        :param request:
        :return:
        """
        book = self.get_object()
        # 3.返回图书信息给客户端
        serializer = self.get_serializer(book)
        return Response(serializer.data)
    def put(self,request,pk):
        """
        4）修改指定的图书的信息（根据ID）；   PUT books/ID/
        :param request:
        :return:
        """
        book = self.get_object()

        serializer = self.get_serializer(book,data=request.data)
        serializer.is_valid()
        serializer.save()
        return Response(serializer.data,status=status.HTTP_200_OK)

    def delete(self,request,pk):
        """
        5）删除指定的图书的信息（根据ID）。   DELETE /books/ID 204
        :param request:
        :return:
        """
        # 1.根据id查询到指定的图书信息
        book = self.get_object()
        # 2.删除指定的图书信息
        book.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)